/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/*
 * HISTORY
 * $Log: mb_iconv.c,v $
 * Revision 1.1.9.1  2000/10/16  18:44:54
 * 	COSIX.Zulu to Yankee merge for GB18030 support.
 *
 * Revision 1.1.7.1  2000/08/07  14:33:49
 * 	Add GBK specific mapping tables for faster processing.
 *
 * Revision 1.1.5.1  2000/01/13  20:25:48
 * 	Remove the old conversion routine in favor of the enhanced
 * 	__<codeset>_index() routine, and add algorithmic UDC conversion
 * 	support. Also add a number of conversion routines to support
 * 	special font charset to Unicode conversion.
 *
 * Revision 1.1.3.2  1996/11/22  17:02:38
 * 	Add support for Unified Hangul (KSC5601-1992).
 * 	[1996/11/14  21:39:52  Long_Man]
 *
 * 	Change cvtab[] from ushort to uint for faster access.
 * 	[1996/10/31  21:50:47  Long_Man]
 *
 * 	Consolidate UCS iconv converter binaries & support UCS-2.
 * 	[1996/10/28  21:11:44  Long_Man]
 *
 * $EndLog$
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
// #include "iconv_local.h"		/* from usr/ccs/lib/libiconv */  // JAC
#include "multi-byte.h"

/*
 * Code range table
 * This table encodes in a byte-by-byte manner the various ranges within
 * 0x00-0xff.  This is used to check if the first or subsequent bytes
 * of a multi-byte character are valid or not.
 *
 * The following ranges are defined :
 *	Bit  0 - 0x21 to 0x3f
 *	Bit  1 - 0x40
 *	Bit  2 - 0x41 to 0x5a
 *	Bit  3 - 0x5b to 0x60
 *	Bit  4 - 0x61 to 0x7a
 *	Bit  5 - 0x7b to 0x7d
 *	Bit  6 - 0x7e
 *	Bit  7 - 0x80
 *	Bit  8 - 0x81 to 0x8d
 *	Bit  9 - 0x8e to 0x9d
 *	Bit 10 - 0x9e
 *	Bit 11 - 0x9f
 *	Bit 12 - 0xa0
 *	Bit 13 - 0xa1 to 0xc6
 *	Bit 14 - 0xc7 to 0xdf
 *	Bit 15 - 0xe0 to 0xf9
 *	Bit 16 - 0xfa to 0xfc
 *	Bit 17 - 0xfd
 *	Bit 18 - 0xfe
 *	Bit 19 - 0x30 to 0x39
 */
const uint __cvtab[] =
{
  0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, /* 0x00-0x07 */
  0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, /* 0x08-0x0f */
  0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, /* 0x10-0x17 */
  0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, /* 0x18-0x1f */

  0x00000, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, /* 0x20-0x27 */
  0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, /* 0x28-0x2f */
  0x80001, 0x80001, 0x80001, 0x80001, 0x80001, 0x80001, 0x80001, 0x80001, /* 0x30-0x37 */
  0x80001, 0x80001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, /* 0x38-0x3f */

  0x00002, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, /* 0x40-0x47 */
  0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, /* 0x48-0x4f */
  0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, 0x00004, /* 0x50-0x57 */
  0x00004, 0x00004, 0x00004, 0x00008, 0x00008, 0x00008, 0x00008, 0x00008, /* 0x58-0x5f */

  0x00008, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, /* 0x60-0x67 */
  0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, /* 0x68-0x6f */
  0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, 0x00010, /* 0x70-0x77 */
  0x00010, 0x00010, 0x00010, 0x00020, 0x00020, 0x00020, 0x00040, 0x00000, /* 0x78-0x7f */

  0x00080, 0x00100, 0x00100, 0x00100, 0x00100, 0x00100, 0x00100, 0x00100, /* 0x80-0x87 */
  0x00100, 0x00100, 0x00100, 0x00100, 0x00100, 0x00100, 0x00200, 0x00200, /* 0x88-0x8f */
  0x00200, 0x00200, 0x00200, 0x00200, 0x00200, 0x00200, 0x00200, 0x00200, /* 0x90-0x97 */
  0x00200, 0x00200, 0x00200, 0x00200, 0x00200, 0x00200, 0x00400, 0x00800, /* 0x98-0x9f */

  0x01000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, /* 0xa0-0xa7 */
  0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, /* 0xa8-0xaf */
  0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, /* 0xb0-0xb7 */
  0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, /* 0xb8-0xbf */

  0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x02000, 0x04000, /* 0xc0-0xc7 */
  0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, /* 0xc8-0xcf */
  0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, /* 0xd0-0xd7 */
  0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, 0x04000, /* 0xd8-0xdf */

  0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, /* 0xe0-0xe7 */
  0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, /* 0xe8-0xef */
  0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, 0x08000, /* 0xf0-0xf7 */
  0x08000, 0x08000, 0x10000, 0x10000, 0x10000, 0x20000, 0x40000, 0x00000  /* 0xf8-0xff */
} ;

const short __gbk_2bidx[] =
{
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x00-0x07 */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x08-0x0f */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x10-0x17 */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x18-0x1f */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x20-0x27 */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x28-0x2f */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x30-0x37 */
   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 0x38-0x3f */
    0,   1,   2,   3,   4,   5,   6,   7,  /* 0x40-0x47 */
    8,   9,  10,  11,  12,  13,  14,  15,  /* 0x48-0x4f */
   16,  17,  18,  19,  20,  21,  22,  23,  /* 0x50-0x57 */
   24,  25,  26,  27,  28,  29,  30,  31,  /* 0x58-0x5f */
   32,  33,  34,  35,  36,  37,  38,  39,  /* 0x60-0x67 */
   40,  41,  42,  43,  44,  45,  46,  47,  /* 0x68-0x6f */
   48,  49,  50,  51,  52,  53,  54,  55,  /* 0x70-0x77 */
   56,  57,  58,  59,  60,  61,  62,  -1,  /* 0x78-0x7f */
   63,  64,  65,  66,  67,  68,  69,  70,  /* 0x80-0x87 */
   71,  72,  73,  74,  75,  76,  77,  78,  /* 0x88-0x8f */
   79,  80,  81,  82,  83,  84,  85,  86,  /* 0x90-0x97 */
   87,  88,  89,  90,  91,  92,  93,  94,  /* 0x98-0x9f */
   95,  96,  97,  98,  99, 100, 101, 102,  /* 0xa0-0xa7 */
  103, 104, 105, 106, 107, 108, 109, 110,  /* 0xa8-0xaf */
  111, 112, 113, 114, 115, 116, 117, 118,  /* 0xb0-0xb7 */
  119, 120, 121, 122, 123, 124, 125, 126,  /* 0xb8-0xbf */
  127, 128, 129, 130, 131, 132, 133, 134,  /* 0xc0-0xc7 */
  135, 136, 137, 138, 139, 140, 141, 142,  /* 0xc8-0xcf */
  143, 144, 145, 146, 147, 148, 149, 150,  /* 0xd0-0xd7 */
  151, 152, 153, 154, 155, 156, 157, 158,  /* 0xd8-0xdf */
  159, 160, 161, 162, 163, 164, 165, 166,  /* 0xe0-0xe7 */
  167, 168, 169, 170, 171, 172, 173, 174,  /* 0xe8-0xef */
  175, 176, 177, 178, 179, 180, 181, 182,  /* 0xf0-0xf7 */
  183, 184, 185, 186, 187, 188, 189,  -1   /* 0xf8-0xff */
} ;

const short __gbk_idx2b[] =
{
  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 
  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 
  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
  0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 
  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
  0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 
  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
  0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 
  0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 
  0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 
  0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 
  0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 
  0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 
  0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 
  0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 
  0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 
  0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 
  0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 
  0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 
  0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 
  0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 
  0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 
  0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 
  0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe  
} ;

/*
 * The program below is used to generate the cvtable conversion table
 * shown above.
 */
#ifdef	GEN_CVTABLE
#include "multi-byte.h"

main()
{
    int idx ;
    int val ;
    int cnt ;

    /*
     * Print the cvtable conversion table.
     */
    printf("const uint __cvtab[] =\n{\n") ;
    for (idx = 0 ; idx <= 0xff ; idx++)
    {
	if ((0x21 <= idx) && (idx <= 0x3f))
	    val = VBIT_21TO3F ;
	else if (idx == 0x40)
	    val = VBIT_40 ;
	else if ((0x41 <= idx) && (idx <= 0x5a))
	    val = VBIT_41TO5A ;
	else if ((0x5b <= idx) && (idx <= 0x60))
	    val = VBIT_5BTO60 ;
	else if ((0x61 <= idx) && (idx <= 0x7a))
	    val = VBIT_61TO7A ;
	else if ((0x7b <= idx) && (idx <= 0x7d))
	    val = VBIT_7BTO7D ;
	else if (idx == 0x7e)
	    val = VBIT_7E ;
	else if (idx == 0x80)
	    val = VBIT_80 ;
	else if ((0x81 <= idx) && (idx <= 0x8d))
	    val = VBIT_81TO8D ;
	else if ((0x8e <= idx) && (idx <= 0x9d))
	    val = VBIT_8ETO9D ;
	else if (idx == 0x9e)
	    val = VBIT_9E ;
	else if (idx == 0x9f)
	    val = VBIT_9F ;
	else if (idx == 0xa0)
	    val = VBIT_A0 ;
	else if ((0xa1 <= idx) && (idx <= 0xc6))
	    val = VBIT_A1TOC6 ;
	else if ((0xc7 <= idx) && (idx <= 0xdf))
	    val = VBIT_C7TODF ;
	else if ((0xe0 <= idx) && (idx <= 0xf9))
	    val = VBIT_E0TOF9 ;
	else if ((0xfa <= idx) && (idx <= 0xfc))
	    val = VBIT_FATOFC ;
	else if (idx == 0xfd)
	    val = VBIT_FD ;
	else if (idx == 0xfe)
	    val = VBIT_FE ;
	else
	    val = 0 ;

	if ((0x30 <= idx) && (idx <= 0x39))
	    val |= VBIT_30TO39 ;
	if ((idx & 0x7) == 0)
	    printf("  ") ;
	printf((idx != 0xff) ? "0x%05x, " : "0x%05x  ", val) ;
	if ((idx & 0x7) == 0x7)
	    printf("/* 0x%02x-0x%02x */\n", idx & ~7, idx) ;
	if (((idx & 0x1f) == 0x1f) && (idx != 0xff))
	    printf("\n") ;
    }
    printf("} ;\n") ;

    /*
     * Print the GBK second byte mapping table
     * 2bidx - Second byte to index table
     * idx2b - index to second byte table
     */
    printf("\nconst short __gbk_2bidx[] =\n{\n") ;
    for (idx = cnt = 0 ; cnt <= 0xff ; cnt++)
    {
	if (((0x40 <= cnt) && (cnt <= 0x7e)) ||
	    ((0x80 <= cnt) && (cnt <= 0xfe)))
	    val = idx++ ;
	else
	    val = -1	;
	if ((cnt & 0x7) == 0)
	    printf("  ") ;
	printf((cnt != 0xff) ? "%3d, " : "%3d  ", val) ;
	if ((cnt & 0x7) == 0x7)
	    printf(" /* 0x%02x-0x%02x */\n", cnt & ~0x7, cnt) ;
    }
    printf("} ;\n") ;

    printf("\nconst short __gbk_idx2b[] =\n{\n") ;
    for (idx = 0, cnt = 0x40 ; cnt <= 0xfe ; cnt++)
    {
	if (cnt == 0x7f) continue ;
	if ((idx & 0x7) == 0)
	    printf("  ") ;
	printf((cnt != 0xfe) ? "0x%02x, " : "0x%02x  ", cnt) ;
	if ((idx & 0x7) == 0x7)
	    printf("\n") ;
	idx++ ;
    }
    printf("\n} ;\n") ;
}
#endif	/* GEN_CVTABLE */
